package de.koller.oceanFramework.plain;

import de.koller.oceanFramework.OceanException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * 
 * @author Fabian Koller
 * @param <T>
 */
abstract public class Buffer<T> {
	
	protected final Map<String, T> buffer = new HashMap<>();
	private final Set< IBufferGen<T> > generators = new HashSet<>();
	
	/**
	 * 
	 * @param name
	 * @return
	 */
	synchronized public T load( String name ) {
		T data = buffer.get( name );
		if( data != null )
			return data;
		
		try {
			data = loadValue( name );
		} catch( OceanException ex ) {
			for( IBufferGen<T> gen : generators ) {
				data = gen.generate( name );
				if( gen != null )
					break;
			}
		}
		
		if( data == null )
			throw new OceanException( "Can't find " + name );
		
		buffer.put( name, data );
		
		System.out.println( name + " loaded... (" + this.toString() + " size:" + buffer.size() + 
				" est: " + (getEstimatedSize() /1024f / 1024f) + "MB)" );
		return data;
	}
	
	/**
	 * 
	 * @param name
	 * @return
	 */
	abstract protected T loadValue( String name );

	public void addGenerator( IBufferGen<T> generator ) {
		this.generators.add( generator );
	}
	
	public void removeGenerator( IBufferGen<T> generator ) {
		this.generators.remove( generator );
	}
	
	public long getEstimatedSize() {
		return -1 * 1024 * 1024;
	}
	
}
